package com.yf.mediaserver.controller;

import cn.hutool.json.JSONUtil;
import com.yf.mediaserver.zlm.ZLMUtil;
import com.yf.mediaserver.zlm.bean.StreamInfo;
import com.yf.mediaserver.zlm.bean.ZLMServerConfig;
import com.yf.mediaserver.zlm.bean.ZlMHookResult;
import com.yf.mediaserver.zlm.bean.hook.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * ZLM HOOK 参数经常变化，为了便于察觉，统一用String接受
 */
@Slf4j
@RestController
@RequestMapping("/index/hook")
public class ZLMHookController {


    /**
     * 播放器鉴权事件，rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。
     */
    @PostMapping("/on_play")
    public ZlMHookResult<?> on_play(@RequestBody String json) {
        log.info(" 播放器鉴权 -> 接受到参数：{}", json);
        return ZlMHookResult.success();
    }


    /**
     * rtsp/rtmp/rtp推流鉴权事件。
     */
    @PostMapping("/on_publish")
    public ZlMHookResult<?> on_publish(@RequestBody String json) {
        OnPublishHookParam publishHookParam = JSONUtil.toBean(json, OnPublishHookParam.class);
        log.info("推流鉴权事件 流媒体服务器:[{}],设备IP:{},schema:{},流ID:{},vhost:{}",
                publishHookParam.getMediaServerId(), publishHookParam.getIp(), publishHookParam.getSchema(), publishHookParam.getStream(), publishHookParam.getVhost()
        );
        return ZlMHookResult.success();
    }

    /**
     * rtsp/rtmp流注册或注销时触发此事件；此事件对回复不敏感。
     */
    @PostMapping("/on_stream_changed")
    public ZlMHookResult<StreamInfo> on_stream_changed(@RequestBody String json) {
        OnStreamChangedHookParam onStreamChangedHookParam = JSONUtil.toBean(json, OnStreamChangedHookParam.class);
        String tag = onStreamChangedHookParam.getRegist() ? "注册" : "注销";
        log.info("流[{}]事件 -> 流媒体服务器：{},流信息:{}", tag, onStreamChangedHookParam.getMediaServerId(), onStreamChangedHookParam);

        String stream = onStreamChangedHookParam.getStream();
        List<TracksBean> tracks = onStreamChangedHookParam.getTracks();
        String callIdParam = "";

        StreamInfo streamInfoResult = new StreamInfo();
        streamInfoResult.setStream(stream);
        streamInfoResult.setApp("rtp");

        ZLMServerConfig mediaInfo = ZLMUtil.getServerConfig();
        String addr = ZLMUtil.ZLM_IP;

        streamInfoResult.setIp(addr);
        streamInfoResult.setMediaServerId(mediaInfo.getMediaServerId());

        streamInfoResult.setRtmp(addr, mediaInfo.getRtmpPort(), mediaInfo.getRtmpSslPort(), streamInfoResult.getApp(), stream, callIdParam);
        streamInfoResult.setRtsp(addr, mediaInfo.getRtspPort(), mediaInfo.getRtspSSlPort(), streamInfoResult.getApp(), stream, callIdParam);
        streamInfoResult.setFlv(addr, mediaInfo.getHttpPort(), mediaInfo.getHttpSSLPort(), streamInfoResult.getApp(), stream, callIdParam);
        streamInfoResult.setFmp4(addr, mediaInfo.getHttpPort(), mediaInfo.getHttpSSLPort(), streamInfoResult.getApp(), stream, callIdParam);
        streamInfoResult.setHls(addr, mediaInfo.getHttpPort(), mediaInfo.getHttpSSLPort(), streamInfoResult.getApp(), stream, callIdParam);
        streamInfoResult.setTs(addr, mediaInfo.getHttpPort(), mediaInfo.getHttpSSLPort(), streamInfoResult.getApp(), stream, callIdParam);
        streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(), mediaInfo.getHttpSSLPort(), streamInfoResult.getApp(), stream, callIdParam);
        streamInfoResult.setTracks(tracks);

        log.info("流{}信息：RTMP {}",tag,streamInfoResult.getRtmp());
        log.info("流{}信息：RTSP {}",tag,streamInfoResult.getRtsp());
        log.info("流{}信息：FLV {}",tag,streamInfoResult.getFlv());
        log.info("流{}信息：HLS {}",tag,streamInfoResult.getHls());
        log.info("流{}信息：TS {}",tag,streamInfoResult.getTs());
        log.info("流{}信息：RTC {}",tag,streamInfoResult.getRtc());
//        streamInfoResult.setDeviceID(deviceId);
//        streamInfoResult.setChannelId(channelId);
        return ZlMHookResult.success();
    }


    /**
     * 流无人观看时事件，用户可以通过此事件选择是否关闭无人看的流。
     */
    @PostMapping("/on_stream_none_reader")
    public ZlMHookResult<?> on_stream_none_reader(@RequestBody String json) {
        OnStreamNoneReaderHookParam onStreamNoneReaderHookParam = JSONUtil.toBean(json, OnStreamNoneReaderHookParam.class);
        log.info("流无人观看 -> 流媒体服务器：{},流信息:{}", onStreamNoneReaderHookParam.getMediaServerId(), onStreamNoneReaderHookParam);
        return ZlMHookResult.success();
    }


    /**
     * 流未找到事件，用户可以在此事件触发时，立即去拉流，这样可以实现按需拉流；此事件对回复不敏感。
     */
    @PostMapping("/on_stream_not_found")
    public ZlMHookResult<?> on_stream_not_found(@RequestBody String json) {
        log.info(" 流未找到 -> 接受到参数：{}", json);
        return ZlMHookResult.success();
    }


    /**
     * 服务器定时上报事件，上报间隔可配置，默认10s上报一次
     */
    @PostMapping("/on_server_keepalive")
    public ZlMHookResult<?> on_server_keepalive(@RequestBody String json) {
        OnServerKeepaliveHookParam onStreamNoneReaderHookParam = JSONUtil.toBean(json, OnServerKeepaliveHookParam.class);
        log.warn("ZLM心跳 -> ID:[{}]", onStreamNoneReaderHookParam.getMediaServerId());
        return ZlMHookResult.success();
    }


    /***
     * 服务器启动事件，可以用于监听服务器崩溃重启；此事件对回复不敏感。
     */
    @PostMapping("/on_server_started")
    public ZlMHookResult<?> on_server_started(@RequestBody String json) {
        log.info(" 服务器启动 -> 接受到参数：{}", json);
        return ZlMHookResult.success();
    }

    /***
     * 发送rtp(startSendRtp)被动关闭时回调
     */
    @PostMapping("/on_send_rtp_stopped")
    public ZlMHookResult<?> on_send_rtp_stopped(@RequestBody String json) {
        log.info("rtp(startSendRtp)被动关闭时 -> 接受到参数：{}", json);
        return ZlMHookResult.success();
    }

    /**
     * rtpServer收流超时
     *
     * @param json
     * @return
     */
    @PostMapping("/on_rtp_server_timeout")
    public ZlMHookResult<?> on_rtp_server_timeout(@RequestBody String json) {
        log.info(" 收流超时 -> 接受到参数：{}", json);
        return ZlMHookResult.success();
    }


}
